#pragma once

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdio>
#include <string>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>

#define Creater 1
#define User 2
#define DefaultFd -1
#define Read O_RDONLY
#define Write O_WRONLY
#define BaseSize 4096

using namespace std;

// 让不同的进程，看到同一份资源----命名管道----通过文件路径

const string comm_path = "./myfifo";

class NamedPipe
{
private:
    bool OpenNamedPipe(int mode)
    {
        _fd = open(_fifo_path.c_str(), mode);
        if (_fd < 0)
            return false;
        return true;
    }

public:
    NamedPipe(const string &path, int who) : _fifo_path(path), _id(who), _fd(DefaultFd)
    {
        if (_id == Creater)
        {
            //.c_str()” 是对string对象的一种操作。它返回一个指向以"空字符结尾"的"字符数组"的指针
            int res = mkfifo(path.c_str(), 0666);
            if (res != 0)
            {
                perror("mkfifo");
            }
            // sleep(5);
            cout << "Creater create namedpipe " << endl;
        }
    }

    bool OpenForRead()
    {
        return OpenNamedPipe(Read);
    }

    bool OpenForWrite()
    {
        return OpenNamedPipe(Write);
    }

    int ReadNamedPipe(string *out)
    {
        char buffer[BaseSize];
        int n = read(_fd, buffer, sizeof(buffer));
        if (n > 0)
        {
            // 为了将字符数组转换为C风格的字符串.将buffer中的最后一个字节设置为0
            // 后将buffer赋值给外部传入的字符串指针out所指向的字符串
            buffer[n] = 0;
            *out = buffer;
        }
        return n;
    }

    int WriteNamedPipe(string &in)
    {
        return write(_fd, in.c_str(), sizeof(in));
    }

    ~NamedPipe()
    {
        if (_id == Creater)
        {
            int res = unlink(_fifo_path.c_str());
            if (res != 0)
            {
                perror("unlink");
            }
            cout << "Creater free namedpipe " << endl;
        }

        if (_fd != DefaultFd)
            close(_fd);
    }

private:
    const string _fifo_path;
    int _id;
    int _fd;
};
